fix(utils): capture entry serial in List.push disposer - #71
Open
buiducnhat wants to merge 1 commit into
Open
Conversation
`List.push()` registers an effect whose disposer closes over `this.sn` — the *mutable* field — rather than the serial number of the entry it created. When a second entry is pushed, `this.sn` advances, so disposing the first entry removes the most recent one instead of its own. The failure is observable on fiber reload: unloading runs the disposers in reverse order, so the first-pushed entry is never removed from the map and is re-pushed on the next load. `list.length` grows and `[...list]` yields stale duplicates (e.g. `["a", "a", "b"]` after one reload). Capture the serial number at push time (matching the core `DisposableList` implementation) so each disposer removes exactly the entry it created.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
@cordisjs/utils'sList.push()registers an effect whose disposer closes overthis.sn— the mutable field — instead of the serial number of the entry it created:Once a second entry is pushed,
this.snhas advanced, so disposing the first entry removes the most recent one rather than its own.This is observable on fiber reload: unloading runs the disposers in reverse order, so the first-pushed entry is never removed and gets re-pushed on the next load.
list.lengthgrows and iterating yields stale duplicates:Fix
Capture the serial number at push time (matching the core
DisposableListimplementation inpackages/core/src/utils.ts), so each disposer removes exactly the entry it created:Tests
Added
packages/utils/tests/index.spec.ts(the@cordisjs/utilspackage previously had no tests) covering:push+ iteration/lengthVerified the regression test fails on
main(['a','a','b']) and passes with the fix. Full suite remains green (165 tests, 20 files).